<?php

namespace utils;

use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\WebSocket\CloseFrame;
use Swoole\Coroutine\Http\Server;
use Swoole\Coroutine\Http\Client;
use function Swoole\Coroutine\run;

class Websocket
{
    public $instance;

    public function start()
    {
        run(function () {
            $server = new Server('0.0.0.0', 9502, false);
            $server->handle('/websocket', function (Request $request, Response $ws) {
                $ws->upgrade();
                global $wsObjects;
                $objectId = spl_object_id($ws);
                $wsObjects[$objectId] = $ws;
                while (true) {
                    $frame = $ws->recv();
                    if ($frame === '') {
                        unset($wsObjects[$objectId]);
                        $ws->close();
                        break;
                    } else if ($frame === false) {
                        echo 'errorCode: ' . swoole_last_error() . "\n";
                        $ws->close();
                        break;
                    } else {
                        if ($frame->data == 'close' || get_class($frame) === CloseFrame::class) {
                            unset($wsObjects[$objectId]);
                            $ws->close();
                            break;
                        }
                        foreach ($wsObjects as $obj) {
                            $obj->push($frame->data);
                        }
                    }
                }
            });

            $server->start();
        });
    }

    public function broadcast(string $content)
    {
        run(function () use ($content) {
            $client = new Client('127.0.0.1', 9502);
            $ret = $client->upgrade('/websocket');
            if ($ret) {
                $client->push($content);
                $client->close();
            }
        });
    }
}
